package managedBean;

import helper.PerformanceHelper;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import beans.*;
import entity.Area;
import entity.Showing;
import exception.ExistException;
import helper.CalendarComparator;
import helper.SeatHelper;
import helper.Seats;
import helper.ShowHelper;
import helper.columnHelper;
import helper.rowHelper;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.logging.Logger;
import javax.ejb.EJB;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import org.primefaces.event.FlowEvent;

/**
 * @Program written by T12 of IS3102/AY2011-12
 */
@ManagedBean
@SessionScoped
public class userPerformanceMB {
    @EJB
    private PerformanceTicketingSBRemote etbr;
    private int numSeats = 0;
    private double cost = 0.00;
    // used for searching
    private String searchVenueName;
    private String searchEventName;
    private String searchDate;
    private String searchGenre;
    private String searchType;
    private Date findDate;
    // used for selected show to purchase
    private String selectedEvent;
    private Long selectedEventId;
    private String selectedSlot;
    private String selectedPoster;
    private String selectedDescription;
    private String selectedVenue;
    private String selectedDateTime;
    private String selectedArea;
    private Long selectedShowId;
    private List<String> selectedSeats;
    private String selectedShowLayout;
    // used for looking info
    private Long infoId;
    private String infoEvent;
    private String infoPoster;
    private String infoDescription;
    private Integer infoDuration;
    private String infoStartDate;
    private String infoEndDate;
    private String infoLanguage;
    private String infoRating;
    private String infoGenre;
    private String infoType;
    private String infoStakeholder;
    private String dates;
    private List<PerformanceHelper> events = new ArrayList<PerformanceHelper>();
    private List<String> venues = new ArrayList<String>();
    private String minDate;
    private String maxDate;
    private SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
    private SimpleDateFormat timeFormat = new SimpleDateFormat("hh:mm aa");
    // used for booking
    private static Logger logger = Logger.getLogger(userPerformanceMB.class.getName());
    private boolean skip;
    // used for purchases
    private String buyShowDate;
    private String buyShowTime;
    private String buyShowSeats;
    private String buyShowVenues;
    private String buyShowAddress;
    private String buyShowTickets;
    private String buyShowArea;
    private Long buyShowAreaId;
    private Double buyShowCost = 0.00;
    private List<String> buyShowAreasList = new ArrayList<String>();
    private DecimalFormat cash = new DecimalFormat("0.00");
    
    /** Creates a new instance of userPerformanceMB */
    public userPerformanceMB() {
        
    }
    
    /*
     * All Accessors and Mutators
     */

    public Long getInfoId() {
        return infoId;
    }

    public void setInfoId(Long infoId) {
        this.infoId = infoId;
    }
    
    public double getCost() {
        return cost;
    }

    public void setCost(double cost) {
        this.cost = cost;
    }

    public int getNumSeats() {
        return numSeats;
    }

    public void setNumSeats(int numSeats) {
        this.numSeats = numSeats;
    }

    public List<PerformanceHelper> getEvents() {
        return events;
    }

    public void setEvents(List<PerformanceHelper> events) {
        this.events = events;
    }
    
    public List<String> getVenues() {
        return venues;
    }

    public void setAllvenue(List<String> venues) {
        this.venues = venues;
    }

    public String getSearchDate() {
        return searchDate;
    }

    public void setSearchDate(String searchDate) {
        this.searchDate = searchDate;
    }

    public Date getFindDate() {
        return findDate;
    }

    public void setFindDate(Date findDate) {
        this.findDate = findDate;
    }

    public String getSearchEventName() {
        return searchEventName;
    }

    public void setSearchEventName(String searchEventName) {
        this.searchEventName = searchEventName;
    }

    public String getSearchVenueName() {
        return searchVenueName;
    }

    public void setSearchVenueName(String searchVenueName) {
        this.searchVenueName = searchVenueName;
    }

    public String getDates() {
        return dates;
    }

    public void setDates(String dates) {
        this.dates = dates;
    }

    public String getMaxDate() {
        return maxDate;
    }

    public void setMaxDate(String maxDate) {
        this.maxDate = maxDate;
    }

    public String getMinDate() {
        return minDate;
    }

    public void setMinDate(String minDate) {
        this.minDate = minDate;
    }

    public String getSelectedEvent() {
        return selectedEvent;
    }

    public void setSelectedEvent(String selectedEvent) {
        this.selectedEvent = selectedEvent;
    }

    public String getSelectedDescription() {
        return selectedDescription;
    }

    public void setSelectedDescription(String selectedDescription) {
        this.selectedDescription = selectedDescription;
    }

    public String getSelectedPoster() {
        return selectedPoster;
    }

    public void setSelectedPoster(String selectedPoster) {
        this.selectedPoster = selectedPoster;
    }

    public String getInfoDescription() {
        return infoDescription;
    }

    public void setInfoDescription(String infoDescription) {
        this.infoDescription = infoDescription;
    }

    public Integer getInfoDuration() {
        return infoDuration;
    }

    public void setInfoDuration(Integer infoDuration) {
        this.infoDuration = infoDuration;
    }

    public String getInfoEndDate() {
        return infoEndDate;
    }

    public void setInfoEndDate(String infoEndDate) {
        this.infoEndDate = infoEndDate;
    }

    public String getInfoEvent() {
        return infoEvent;
    }

    public void setInfoEvent(String infoEvent) {
        this.infoEvent = infoEvent;
    }

    public String getInfoGenre() {
        return infoGenre;
    }

    public void setInfoGenre(String infoGenre) {
        this.infoGenre = infoGenre;
    }

    public String getInfoLanguage() {
        return infoLanguage;
    }

    public void setInfoLanguage(String infoLanguage) {
        this.infoLanguage = infoLanguage;
    }

    public String getInfoPoster() {
        return infoPoster;
    }

    public void setInfoPoster(String infoPoster) {
        this.infoPoster = infoPoster;
    }

    public String getInfoRating() {
        return infoRating;
    }

    public void setInfoRating(String infoRating) {
        this.infoRating = infoRating;
    }

    public String getInfoStartDate() {
        return infoStartDate;
    }

    public void setInfoStartDate(String infoStartDate) {
        this.infoStartDate = infoStartDate;
    }

    public String getInfoType() {
        return infoType;
    }

    public void setInfoType(String infoType) {
        this.infoType = infoType;
    }

    public String getSearchGenre() {
        return searchGenre;
    }

    public void setSearchGenre(String searchGenre) {
        this.searchGenre = searchGenre;
    }

    public String getSearchType() {
        return searchType;
    }

    public void setSearchType(String searchType) {
        this.searchType = searchType;
    }

    public String getSelectedVenue() {
        return selectedVenue;
    }

    public void setSelectedVenue(String selectedVenue) {
        this.selectedVenue = selectedVenue;
    }

    public String getSelectedArea() {
        return selectedArea;
    }

    public void setSelectedArea(String selectedArea) {
        this.selectedArea = selectedArea;
    }

    public List<String> getSelectedSeats() {
        return selectedSeats;
    }

    public void setSelectedSeats(List<String> selectedSeats) {
        this.selectedSeats = selectedSeats;
    }

    public Long getSelectedEventId() {
        return selectedEventId;
    }

    public void setSelectedEventId(Long selectedEventId) {
        this.selectedEventId = selectedEventId;
    }

    public String getSelectedDateTime() {
        return selectedDateTime;
    }

    public void setSelectedDateTime(String selectedDateTime) {
        this.selectedDateTime = selectedDateTime;
    }

    public Long getSelectedShowId() {
        return selectedShowId;
    }

    public void setSelectedShowId(Long selectedShowId) {
        this.selectedShowId = selectedShowId;
    }

    public String getSelectedSlot() {
        return selectedSlot;
    }

    public void setSelectedSlot(String selectedSlot) {
        this.selectedSlot = selectedSlot;
    }

    public String getSelectedShowLayout() {
        return selectedShowLayout;
    }

    public void setSelectedShowLayout(String selectedShowLayout) {
        this.selectedShowLayout = selectedShowLayout;
    }

    public String getInfoStakeholder() {
        return infoStakeholder;
    }

    public void setInfoStakeholder(String infoStakeholder) {
        this.infoStakeholder = infoStakeholder;
    }

    public String getBuyShowAddress() {
        return buyShowAddress;
    }

    public void setBuyShowAddress(String buyShowAddress) {
        this.buyShowAddress = buyShowAddress;
    }

    public String getBuyShowArea() {
        return buyShowArea;
    }

    public void setBuyShowArea(String buyShowArea) {
        this.buyShowArea = buyShowArea;
    }

    public String getBuyShowDate() {
        return buyShowDate;
    }

    public void setBuyShowDate(String buyShowDate) {
        this.buyShowDate = buyShowDate;
    }

    public String getBuyShowSeats() {
        return buyShowSeats;
    }

    public void setBuyShowSeats(String buyShowSeats) {
        this.buyShowSeats = buyShowSeats;
    }

    public String getBuyShowTickets() {
        return buyShowTickets;
    }

    public void setBuyShowTickets(String buyShowTickets) {
        this.buyShowTickets = buyShowTickets;
    }

    public String getBuyShowTime() {
        return buyShowTime;
    }

    public void setBuyShowTime(String buyShowTime) {
        this.buyShowTime = buyShowTime;
    }

    public String getBuyShowVenues() {
        return buyShowVenues;
    }

    public void setBuyShowVenues(String buyShowVenues) {
        this.buyShowVenues = buyShowVenues;
    }

    public List<String> getBuyShowAreasList() {
        return buyShowAreasList;
    }

    public void setBuyShowAreasList(List<String> buyShowAreasList) {
        this.buyShowAreasList = buyShowAreasList;
    }
    
    public Double getBuyShowCost() {
        return buyShowCost;
    }

    public void setBuyShowCost(Double buyShowCost) {
        this.buyShowCost = buyShowCost;
    }

    public Long getBuyShowAreaId() {
        return buyShowAreaId;
    }

    public void setBuyShowAreaId(Long buyShowAreaId) {
        this.buyShowAreaId = buyShowAreaId;
    }
    
    /*
     * Methods used in jsf
     */
    public String findingMinDate(){
        Calendar temp = Calendar.getInstance();
        Date dateTemp = temp.getTime();
        minDate = sdf.format(dateTemp);
        return minDate;
    }
    
    public String findingMaxDate(){
        Calendar temp = Calendar.getInstance();
        temp.add(Calendar.MONTH, 3);
        Date dateTemp = temp.getTime();
        maxDate = sdf.format(dateTemp);
        return maxDate;
    }
    
    public List<PerformanceHelper> getAllShows(){
        events = new ArrayList<PerformanceHelper>();
        events = etbr.getShows();
        return events;
    }

    public List<String> getAllActiveVenues(){
        venues = new ArrayList<String>();
        venues = etbr.getAllActiveVenues();
        return venues;
    }
    
    public List<PerformanceHelper> getAvailableShows(){
        events = new ArrayList<PerformanceHelper>();
        events = etbr.getNowShowing();
        return events;
    }
    
    public List<PerformanceHelper> getComingSoon(){
        events = new ArrayList<PerformanceHelper>();
        events = etbr.getComingSoon();
        return events;
    }
    
    public List<PerformanceHelper> searchAvailableShows(){
        int count = 1;
        List<PerformanceHelper> output = new ArrayList<PerformanceHelper>();
        searchEventName = convertEventName();
        searchDate = convertDate();
        searchVenueName = convertVenue();
        searchGenre = convertGenre();
        searchType = convertType();
        System.out.println("Available:");
        System.out.println(searchDate + " : " + searchVenueName + " : " + searchGenre + " : " + searchType + " : " + searchEventName);
        for(PerformanceHelper e: getAvailableShows()){
            //System.out.println("Event #" + count);
            int counting = 1;
            for(ShowHelper s: e.getShowings()){
                /*System.out.println("Event #" + counting);
                System.out.println("Compare " + s.getVenue() + " with " + searchVenueName + ": " + s.getVenue().contains(searchVenueName));
                System.out.println("Compare " + e.getEventName() + " with " + searchEventName + ": " + e.getEventName().contains(searchEventName));
                System.out.println("Compare " + s.getTiming() + " with " + searchDate + ": " + s.getTiming().contains(searchDate));*/
                if(s.getVenue().toUpperCase().contains(searchVenueName.toUpperCase()) && e.getEventName().toUpperCase().contains(searchEventName.toUpperCase()) && s.getTiming().contains(searchDate)
                  && e.getGenre().toUpperCase().contains(searchGenre.toUpperCase()) && e.getType().toUpperCase().contains(searchType.toUpperCase())){
                    output.add(e);
                    break;
                }
                counting++;
            }
            count++;
        }
        return output;
    }
    
    public List<PerformanceHelper> searchComingSoon(){
        int count = 1;
        List<PerformanceHelper> output = new ArrayList<PerformanceHelper>();
        searchEventName = convertEventName();
        searchDate = convertDate();
        searchVenueName = convertVenue();
        searchGenre = convertGenre();
        searchType = convertType();
        System.out.println("Coming Soon:");
        System.out.println(searchDate + " : " + searchVenueName + " : " + searchGenre + " : " + searchType + " : " + searchEventName);
        for(PerformanceHelper e: getComingSoon()){
            //System.out.println("Event #" + count);
            int counting = 1;
            for(ShowHelper s: e.getShowings()){
                /*System.out.println("Event #" + counting);
                System.out.println("Compare " + s.getVenue() + " with " + searchVenueName + ": " + s.getVenue().contains(searchVenueName));
                System.out.println("Compare " + e.getEventName() + " with " + searchEventName + ": " + e.getEventName().contains(searchEventName));
                System.out.println("Compare " + s.getTiming() + " with " + searchDate + ": " + s.getTiming().contains(searchDate));*/
                if(s.getVenue().toUpperCase().contains(searchVenueName.toUpperCase()) && e.getEventName().toUpperCase().contains(searchEventName.toUpperCase()) && s.getTiming().contains(searchDate)
                  && e.getGenre().toUpperCase().contains(searchGenre.toUpperCase()) && e.getType().toUpperCase().contains(searchType.toUpperCase())){
                    output.add(e);
                    break;
                }
                counting++;
            }
            count++;
        }
        return output;
    }
    
    public String convertEventName(){
        if(searchEventName == null){
            searchEventName = "";
        }
        return searchEventName;
    }
    
    public String convertDate(){
        if(findDate != null){
            searchDate = sdf.format(findDate);
        }else{
            searchDate = "";
        }
        return searchDate;
    }
    
    public String convertVenue(){
        if(searchVenueName == null){
            searchVenueName = "";
        }
        return searchVenueName;
    }
    
    public String convertGenre(){
        if(searchGenre == null){
            searchGenre = "";
        }
        return searchGenre;
    }
    
    public String convertType(){
        if(searchType == null){
            searchType = "";
        }
        return searchType;
    }
    
    public String searchAvailableShowResults(){
        if(searchAvailableShows().isEmpty()){
            return "No Shows Available";
        }else{
            return "Search Results (Displaying " + searchAvailableShows().size() + " results)";
        }
    }
    
    public String searchComingSoonResults(){
        List<PerformanceHelper> temp = searchComingSoon();
        if(temp.isEmpty()){
            return "No Shows Available";
        }else{
            return "Search Results (Displaying " + searchComingSoon().size() + " results)";
        }
    }
    
    public String onFlowProcess(FlowEvent event){
        logger.info("Current Wizard Step:" + event.getOldStep());
        logger.info("Next Step:" + event.getNewStep());
        System.out.println(event.getOldStep());
        System.out.println(event.getNewStep());
        if(event.getNewStep().equalsIgnoreCase("selectArea") && event.getOldStep().equalsIgnoreCase("selectTiming")){
            String selectedSlot = this.getSelectedSlot();
            Long selectedEventId = this.getSelectedEventId();
            Showing show = new Showing();
            show = etbr.getSelectedShow(selectedEventId, selectedSlot);
            System.out.println(show.getVenue().getName());
            this.setBuyShowAddress(show.getVenue().getAddress());
            this.setBuyShowVenues(show.getVenue().getName());
            this.setBuyShowDate(sdf.format(show.getShowDate().getTime()));
            this.setBuyShowTime(timeFormat.format(show.getShowDate().getTime()));
            buyShowAreasList.clear();
            for(Area a: show.getAreas()){
                Double tempCost = a.getCost();
                String tempArea = a.getAreaName();
                String choice = tempArea + " ($" + cash.format(tempCost) + ")";
                System.out.println(choice);
                this.buyShowAreasList.add(choice);
            }
        }else if(event.getNewStep().equalsIgnoreCase("selectSeat") && event.getOldStep().equalsIgnoreCase("selectArea")){
            System.out.println(this.selectedArea);
            String areaname = selectedArea.substring(0, selectedArea.indexOf(" ("));
            this.buyShowArea = areaname;
            this.cost = Double.valueOf(selectedArea.substring(selectedArea.indexOf("$") + 1, selectedArea.indexOf(")")));
            System.out.println("Area Name: " + areaname);
            System.out.println("Cost: " + cost);
            Showing show = new Showing();
            show = etbr.getSelectedShow(selectedEventId, selectedSlot);
            for(Area a: show.getAreas()){
                System.out.println(a.getAreaName() + " vs " + areaname + " = " + a.getAreaName().equalsIgnoreCase(areaname));
                if(a.getAreaName().equalsIgnoreCase(areaname)){
                    System.out.println(a.getId());
                    this.buyShowAreaId = new Long(a.getId());
                }
            }
        }else if(event.getNewStep().equalsIgnoreCase("confirmation") && event.getOldStep().equalsIgnoreCase("selectSeat")){
            this.buyShowTickets = "";
        }else if(event.getNewStep().equalsIgnoreCase("selectSeat") && event.getOldStep().equalsIgnoreCase("confirmation")){
            this.buyShowCost = 0.00;
            System.out.println("BuyShowCost: " + this.buyShowCost);
        }else if(event.getNewStep().equalsIgnoreCase("selectArea") && event.getOldStep().equalsIgnoreCase("selectSeat")){
        }else if(event.getNewStep().equalsIgnoreCase("selectTiming") && event.getOldStep().equalsIgnoreCase("selectArea")){
        }
        if(skip){
            skip = false;
            return "confirm";
        }else{
            return event.getNewStep();
        }
    }
    
    public List<String> getSpecificShows(Long eventId){
        List<ShowHelper> temp = new ArrayList<ShowHelper>();
        temp = etbr.getSpecificShows(eventId);
        List<String> output = new ArrayList<String>();
        for(ShowHelper s: temp){
            output.add(s.getTiming() + " (" + s.getVenue() + ")");
        }
        return output;
    }
    
    public String selectDateTime(String slot){
        return slot.substring(numSeats);
    }
    
    /*public String findStakeholder(Long eventId){
        System.out.println("findStakeholder: " + eventId);
        try{
            infoStakeholder = etbr.getEventOrganiser(eventId);
            return infoStakeholder;
        }catch(ExistException e){
            return e.getMessage();
        }
    }*/
    
    public Long findSelectedShowId(){
        String slot = getSelectedSlot();
        Long id = this.getSelectedEventId();
        Long output = new Long(-1);
        System.out.println(slot);
        List<ShowHelper> temp = new ArrayList<ShowHelper>();
        temp = etbr.getSpecificShows(id);
        for(ShowHelper s: temp){
            String check = s.getTiming() + " (" + s.getVenue() + ")";
            if(check.equals(slot)){
                output = s.getId();
                break;
            }
        }
        this.selectedShowId = output;
        System.out.println("output: " + output);
        return output;
    }
    
    public List<Integer> getAllColumns(Long areaid){
        List<Integer> output = new ArrayList<Integer>();
        boolean check = etbr.isAreaNull(areaid);
        if(!check){
            Seats[][] temp = etbr.getSeats(areaid);
            for (int j = 0; j < temp[0].length; j++) {
                output.add(temp[0][j].getColumn());
            }
        }
        return output;
    }
    
    public List<String> getAllRows(Long areaid){
        List<String> output = new ArrayList<String>();
        boolean check = etbr.isAreaNull(areaid);
        if(!check){
            Seats[][] temp = etbr.getSeats(areaid);
            for (int i = 0; i < temp.length; i++) {
                output.add(temp[i][0].getRow());
            }
        }
        return output;
    }
    
    public List<rowHelper> getAllSeats(Long areaid){
        List<rowHelper> output = new ArrayList<rowHelper>();
        boolean check = etbr.isAreaNull(areaid);
        if(!check){
            Seats[][] temp = etbr.getSeats(areaid);
            for (int i = 0; i < temp.length; i++) {
                List<columnHelper> colList = new ArrayList<columnHelper>();
                for (int j = 0; j < temp[i].length; j++) {
                    columnHelper seat = new columnHelper();
                    seat.setColumn(+(temp[i][j].getColumn()));
                    if (temp[i][j].isEmpty()) {
                        seat.setImagePath("picture/EmptySpaceSeat.gif");
                    } else {
                        if (temp[i][j].isReserved()) {
                            seat.setImagePath("picture/OccupiedSeat.gif");
                        } else {
                            seat.setImagePath("picture/AvailableSeat.gif");
                        }
                    }
                    colList.add(seat);
                }
                rowHelper row = new rowHelper(String.valueOf(temp[i][0].getRow()), colList);
                output.add(row);
            }
        }
        return output;
    }
    
    public void setSelectedEvent(){
        
    }
    
    public void specificEvents(ActionListener listener){
        
    }
    
    public void redirectSelectShowToSearchEvent(ActionEvent event) throws IOException
    {
        System.out.println("******** searchEventName: " + searchEventName);
        FacesContext.getCurrentInstance().getExternalContext().redirect("searchevents.xhtml?faces-redirect=true");
    }
}
